﻿namespace Mockingbird.Repository.MongoDB.Repository.Account
{
    using System.Collections.Generic;
    using System.Linq;
    using Core.Models;
    using Core.Repository;
    using global::MongoDB.Bson;
    using global::MongoDB.Driver;
    using global::MongoDB.Driver.Builders;

    public class AccountRepository : IAccountRepository
    {
        private MongoCollection<UserPropertiesModel> userCollection;

        public AccountRepository(MongoCollection<UserPropertiesModel> userCollection)
        {
            this.userCollection = userCollection;
        }

        public bool ValidateUser(string email, string password)
        {
            var query = Query.And(
                Query.EQ("Email", email),
                Query.EQ("Password", password)
            );

            return userCollection.Find(query).Count() == 1;
        }

        public UserPropertiesModel GetUser(string email)
        {
            var query = Query.EQ("Email", email);

            return userCollection.FindOne(query);
        }

        public List<UserPropertiesModel> SearchUsers(string name)
        {
            List<UserPropertiesModel> users = userCollection.Find(Query.Matches("Name", name)).ToList();

            return users;
        }

        public bool RegisterUser(UserPropertiesModel user)
        {
            if (userCollection.Find(Query.EQ("Email", user.Email)).Any())
            {
                return false;
            }

            userCollection.Insert(user);

            return true;
        }

        public UserPropertiesModel FollowUser(ObjectId follower, string user)
        {
            var query = Query<UserPropertiesModel>.EQ(u => u.Id, follower);

            var followerModel = userCollection.Find(query).FirstOrDefault();

            if (followerModel != null)
            {
                if (followerModel.Friends == null)
                {
                    followerModel.Friends = new List<ObjectId>();
                }

                followerModel.Friends.Add(new ObjectId(user));

                userCollection.Save(followerModel);

                return followerModel;
            }

            return null;
        }

        public UserPropertiesModel UnfollowUser(ObjectId id, string userId)
        {
            var query = Query<UserPropertiesModel>.EQ(u => u.Id, id);

            var followerModel = userCollection.Find(query).FirstOrDefault();

            if (followerModel != null)
            {
                if (followerModel.Friends == null)
                {
                    followerModel.Friends = new List<ObjectId>();
                }

                followerModel.Friends.Remove(new ObjectId(userId));

                userCollection.Save(followerModel);

                return followerModel;
            }

            return null;
        }

        public UserPropertiesModel GetUserById(string userId)
        {
            var query = Query<UserPropertiesModel>.EQ(u => u.Id, new ObjectId(userId));

            return userCollection.FindOne(query);
        }
    }
}
